<?php
/**
 * 使用 memcache 的缓存类
 * @author Rox <rox@taomee.com>
 *
 *      key -> server 的对应关系由 memcache 模块自动实现，它的行为由 php.ini 配置 memcache.hash_strategy 控制
 *      数据有效性（是否过期）检查是自动的，无需手动调用 isValid() 检查
 */
class Mcache
{
    var $cache_lifetime;   // 缓存过期时间
    var $version_number;   // 缓存内容版本号
    var $memcache;         // memcache 对象

    /**
     * 构造函数
     */
    function __construct($cache_lifetime = 0, $version=1)
    {
        global $sys_conf_var;
        $this->cache_lifetime = $cache_lifetime > 0 ? $cache_lifetime : $sys_conf_var['system']['cache_life_time'];
        $this->version_number = $version;

        if ( !class_exists('Memcache') )
        {
            throw new AppException('Memcache module not found.');
        }

        // set up memcache object
        $this->initMemcache();
    }

    /**
     * 得到缓存数据
     * @param $app_name      //应用名称
     * @param $var_name      //保存缓存的变量名
     * @return $data         //缓存的数组或字符串
     */
    function getCache($app_name, $var_name = '')
    {
        return unserialize($this->memcache->get($this->getKey($app_name, $var_name)));
    }

    /**
     * 设置缓存数据
     * @param $app_name    //应用名称
     * @param $var_name    //保存缓存的变量名
     * @param $data        //需要缓存的数组或字符串
     * @param $cache_lifetime //缓存生效时间，默认为NULL，使用类默认的 $this->cache_lifetime
     * @return boolean
     */
    function setCache($app_name, $var_name, $data, $cache_lifetime=NULL)
    {
        if (!$cache_lifetime)
        {
            $cache_lifetime = $this->cache_lifetime;
        }
        return $this->memcache->set($this->getKey($app_name, $var_name), serialize($data), NULL, $cache_lifetime);
    }

    /**
     * 清除指定缓存
     * @param $app_name    // 应用名称
     * @param $var_name    // 保存缓存的变量名
     * @return boolean
     */
    function clearCache($app_name, $var_name)
    {
        return $this->memcache->delete($this->getKey($app_name, $var_name));
    }

    /**
     * 返回服务器状态
     */
    function serverStatus()
    {
        return $this->memcache->getExtendedStats();
    }

    /**
     * 生成 memcache 所用的 key
     * @param  $app_name
     * @param  $var_name
     * @global $sys_conf_var
     * @return string
     */
    private function getKey($app_name, $var_name)
    {
        if (!is_string($var_name) && is_array($var_name))
        {
            $var_name = implode('|', $var_name);
        }

        $result = md5('[' . $this->version_number . ']' . $app_name . '.' . $var_name);

        // prepend domain name
        global $sys_conf_var;
        $result = $sys_conf_var['system']['domain'] . '|' . $result;

        return $result;
    }

    /**
     * 初始化 memcache 对象
     */
    private function initMemcache()
    {
        $this->memcache = new Memcache;

        global $sys_conf_var;
        $arr_cache_setting = explode(',', $sys_conf_var['memcache']['serv_ip']);

        if ( empty($arr_cache_setting) || empty($arr_cache_setting[0]) )
        {
            throw new AppException('Bad memcache config.');
        }

        foreach($arr_cache_setting as $v)
        {
            $setting = parse_url($v);

            $host = $setting['host'];
            $port = $setting['port'];

            if ( !$host || !$port ) continue;

            parse_str($setting['query'],$arr_query);
            $persistent = $arr_query['persistent'];
            $weight     = @intval($arr_query['weight']);
            $timeout    = $arr_query['timeout'];

            if ( !$weight )
            {
                $weight = 1;
            }

            $this->memcache->addServer($host, $port, $persistent, $weight, $timeout);
        }
    }
}
?>
